<template>
  <div class="file-explorer">
    <div class="explorer-header">
      <!-- 操作栏：视图切换和操作按钮 -->
      <ActionBar 
        v-model:view-mode="viewMode"
        :loading="loading"
        :can-upload="canUpload"
        :can-create-folder="canCreateFolder"
        @refresh="refreshFiles"
        @show-upload-dialog="showUploadDialog"
        @show-create-folder-dialog="showCreateFolderDialog"
      />
      
      <!-- 搜索和筛选 -->
      <SearchFilter
        v-model:search-query="searchQuery"
        v-model:category-filter="categoryFilter"
        v-model:type-filter="typeFilter"
        :categories="categories"
        @search="debouncedSearch"
      />
      
      <!-- 面包屑导航 -->
      <BreadcrumbNav
        :current-path="filePreviewStore.currentPath"
        :breadcrumb-parts="filePreviewStore.getBreadcrumbParts"
      />
    </div>
    
    <div class="explorer-body">
      <!-- 加载状态 -->
      <div v-if="props.useCosService ? filePreviewStore.loading : loading" class="loading-container">
        <el-skeleton :rows="15" animated :throttle="500">
          <template #template>
            <div class="skeleton-wrapper">
              <div class="skeleton-header">
                <el-skeleton-item variant="image" style="width: 36px; height: 36px; margin-right: 16px" />
                <el-skeleton-item variant="p" style="width: 50%" />
              </div>
              <div class="skeleton-content">
                <div v-for="i in 8" :key="i" class="skeleton-item">
                  <el-skeleton-item variant="image" style="width: 36px; height: 36px; margin-right: 16px" />
                  <el-skeleton-item variant="p" style="width: 60%" />
                </div>
              </div>
            </div>
          </template>
        </el-skeleton>
      </div>
      
      <!-- 非加载状态下的内容 -->
      <div v-if="!(props.useCosService ? filePreviewStore.loading : loading)">
        <!-- 空状态 -->
        <div v-if="filteredFiles.length === 0" class="empty-container">
          <el-empty
            description="没有找到文件"
            class="empty-state"
          />
        </div>
        
        <!-- 文件视图（网格或列表） -->
        <FileView
          v-else
          :view-mode="viewMode"
          :filtered-files="filteredFiles"
          :selected-file="selectedFile"
          :can-delete="canDelete"
          @file-click="handleFileClick"
          @file-dbl-click="handleFileDblClick"
          @preview="previewFile"
          @download="downloadFile"
          @open="openFileInReader"
          @info="showFileInfo"
          @delete="confirmDeleteFile"
        />
      </div>
    </div>
    
    <!-- 各种对话框 -->
    <DialogContainer
      v-model:preview-dialog-visible="previewDialogVisible"
      v-model:file-info-dialog-visible="fileInfoDialogVisible"
      v-model:create-folder-dialog-visible="createFolderDialogVisible"
      v-model:upload-dialog-visible="uploadDialogVisible"
      :selected-file="selectedFile"
      :folder-form="folderForm"
      :upload-files="uploadFiles"
      :uploading="uploading"
      :creating-folder="creatingFolder"
      :is-mobile="isMobile"
      :current-path="currentPath"
      :is-document-file="isDocumentFile"
      :get-document-type="getDocumentType"
      :get-file-type-label="getFileTypeLabel"
      @handle-file-change="handleFileChange"
      @upload-selected-files="uploadSelectedFiles"
      @create-folder="createFolder"
      @open-file-in-reader="openFileInReader"
      @download-file="downloadFile"
    />
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'FileExplorer'
});
</script>

<script setup>
import { ref, computed, watch, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { useRouter } from 'vue-router';
import { useMainStore, useFilePreviewStore, usePermissionStore } from '../../store';
import cosFileService from '../../services/CosFileService';

// 导入拆分出的子组件
import ActionBar from './ActionBar.vue';
import SearchFilter from './SearchFilter.vue';
import BreadcrumbNav from './BreadcrumbNav.vue';
import FileView from './FileView.vue';
import DialogContainer from './DialogContainer.vue';
import { isDocumentFile, getDocumentType, getFileTypeLabel } from './utils/fileHelpers';
import { debounce } from './utils/helpers';

const props = defineProps({
  // 是否使用COS服务，如果为false则使用传入的files
  useCosService: {
    type: Boolean,
    default: false
  },
  // COS服务配置
  cosConfig: {
    type: Object,
    default: () => ({})
  },
  // 文件列表，当useCosService为false时使用
  files: {
    type: Array,
    default: () => []
  },
  // 是否正在加载
  loading: {
    type: Boolean,
    default: false
  },
  // 是否可以预览文件
  previewInDialog: {
    type: Boolean,
    default: true
  },
  // 是否可以上传文件
  canUpload: {
    type: Boolean,
    default: false
  },
  // 是否可以创建文件夹
  canCreateFolder: {
    type: Boolean,
    default: false
  },
  // 是否可以删除文件
  canDelete: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits([
  'file-read', 
  'file-download', 
  'file-preview', 
  'refresh',
  'file-upload',
  'folder-create',
  'file-delete'
]);

// 获取store和router
const store = useMainStore();
const filePreviewStore = useFilePreviewStore();
const permissionStore = usePermissionStore();
const router = useRouter();

// 状态管理
const searchQuery = ref('');
const categoryFilter = ref('');
const typeFilter = ref('');
const viewMode = ref('grid'); // 默认网格视图
const previewDialogVisible = ref(false);
const fileInfoDialogVisible = ref(false);
const createFolderDialogVisible = ref(false);
const uploadDialogVisible = ref(false);
const selectedFile = ref(null);
const currentPath = ref('');
const internalFiles = ref([]);
const internalLoading = ref(false);
const creatingFolder = ref(false);
const folderForm = ref({ name: '' });
const uploadFiles = ref([]);
const uploading = ref(false);

// 面包屑导航
const breadcrumbParts = computed(() => {
  if (!currentPath.value) return [];
  
  // 分割路径并过滤空字符串
  const parts = currentPath.value.split('/').filter(Boolean);
  
  // 构建面包屑导航项
  return parts.map((part, index) => {
    // 构建到当前部分的路径
    const path = parts.slice(0, index + 1).join('/');
    return { name: part, path };
  });
});

// 检测是否为移动设备
const isMobile = computed(() => {
  return window.innerWidth <= 768;
});

// 计算所有分类
const categories = computed(() => {
  const categorySet = new Set();
  
  const extractCategories = (items) => {
    items.forEach(item => {
      if (item.category) categorySet.add(item.category);
      if (item.children) extractCategories(item.children);
    });
  };
  
  extractCategories(getDisplayFiles.value);
  return Array.from(categorySet);
});

// 获取显示的文件列表
const getDisplayFiles = computed(() => {
  return props.useCosService ? internalFiles.value : props.files;
});

// 过滤文件 - 优化性能
const filteredFiles = computed(() => {
  const files = props.useCosService ? filePreviewStore.files : props.files;
  
  // 如果没有搜索条件，直接返回所有文件
  if (!searchQuery.value && !categoryFilter.value && !typeFilter.value) {
    return files;
  }
  
  // 预处理搜索条件，避免在循环中重复计算
  const searchLower = searchQuery.value.toLowerCase();
  const hasSearchQuery = searchQuery.value.length > 0;
  const hasCategoryFilter = categoryFilter.value.length > 0;
  const hasTypeFilter = typeFilter.value.length > 0;
  
  return files.filter(file => {
    // 名称匹配 - 使用预处理的小写字符串
    const nameMatch = !hasSearchQuery || file.name.toLowerCase().includes(searchLower);
    
    // 分类匹配 - 避免不必要的比较
    const categoryMatch = !hasCategoryFilter || file.category === categoryFilter.value;
    
    // 类型匹配 - 避免不必要的比较
    const typeMatch = !hasTypeFilter || file.type === typeFilter.value;
    
    return nameMatch && categoryMatch && typeMatch;
  });
});

// 搜索处理 - 优化性能
const handleSearch = () => {
  const resultCount = filteredFiles.value.length;
  const hasFilters = searchQuery.value || categoryFilter.value || typeFilter.value;
  
  // 只在开发环境输出日志
  if (process.env.NODE_ENV === 'development') {
    console.log('执行搜索:', { 
      查询: searchQuery.value, 
      分类: categoryFilter.value,
      类型: typeFilter.value,
      结果数量: resultCount 
    });
  }
  
  // 如果搜索结果为空且有筛选条件，显示提示
  if (resultCount === 0 && hasFilters) {
    const filterParts = [];
    if (categoryFilter.value) filterParts.push(`分类：${categoryFilter.value}`);
    if (typeFilter.value) filterParts.push(`类型：${typeFilter.value}`);
    
    ElMessage({
      type: 'info',
      message: `未找到匹配的文件${filterParts.length ? `（${filterParts.join('，')}）` : ''}`,
      duration: 2000
    });
  }
  
  // 如果搜索结果只有一个文件且有搜索词，自动选中但不打开
  if (resultCount === 1 && searchQuery.value) {
    selectedFile.value = filteredFiles.value[0];
  } else if (resultCount > 1) {
    // 多个结果时清空选中状态
    selectedFile.value = null;
  }
};

// 使用防抖处理的搜索函数 - 优化延迟时间
const debouncedSearch = debounce(handleSearch, 200);

// 监听搜索条件变化 - 优化性能
watch([searchQuery, categoryFilter, typeFilter], (newValues, oldValues) => {
  // 只有在值真正改变时才触发搜索
  const hasChanged = newValues.some((value, index) => value !== oldValues[index]);
  if (hasChanged) {
    debouncedSearch();
  }
}, { deep: false });

// 处理文件点击 - 优化性能
const handleFileClick = async (file) => {
  // 只在开发环境输出日志
  if (process.env.NODE_ENV === 'development') {
    console.log('文件点击:', file.name, file.type);
  }
  
  // 如果已经选中相同文件，则取消选中
  if (selectedFile.value?.name === file.name && selectedFile.value?.type === file.type) {
    selectedFile.value = null;
    return;
  }
  
  // 设置选中的文件
  selectedFile.value = file;
  
  // 如果是目录，导航到该目录
  if (file.type === 'directory') {
    try {
      // 构建路径 - 优化路径处理
      let path;
      if (file.prefix) {
        // 从前缀中提取路径，确保移除COS前缀和多余斜杠
        path = file.prefix.replace(cosFileService.config.Prefix, '').replace(/\/+$/, '');
      } else {
        // 构建路径，确保不会有多余斜杠
        const currentPath = filePreviewStore.currentPath;
        path = currentPath ? `${currentPath}/${file.name}` : file.name;
      }
      
      // 先清空文件列表，避免动画闪烁
      filePreviewStore.clearFiles();
      
      // 并行执行导航和路由更新
      await Promise.all([
        filePreviewStore.navigateTo(path),
        router.push({
          name: 'FileBrowser',
          params: { path }
        })
      ]);
      
      if (process.env.NODE_ENV === 'development') {
        console.log('文件夹点击导航完成, 当前路径:', path);
      }
    } catch (err) {
      // 忽略重复导航错误
      if (err.name !== 'NavigationDuplicated') {
        console.error('导航错误:', err);
        ElMessage.error('导航失败，请重试');
      }
    }
  }
};

// 处理文件双击 - 优化性能
const handleFileDblClick = async (file) => {
  if (process.env.NODE_ENV === 'development') {
    console.log('文件双击:', file);
  }
  
  if (file.type === 'directory') {
    // 如果是目录，导航到该目录
    await handleFileClick(file);
  } else {
    // 如果是文件，预览或打开文件
    if (props.previewInDialog) {
      previewFile(file);
    } else {
      openFileInReader(file);
    }
  }
};

// 导航到指定路径 - 优化性能
const navigateTo = async (path) => {
  if (process.env.NODE_ENV === 'development') {
    console.log('导航到路径:', path);
  }
  await filePreviewStore.navigateTo(path);
};

// 从COS加载文件 - 优化性能
const loadFilesFromCos = async () => {
  if (!props.useCosService || !cosFileService.isInitialized) {
    console.error('COS服务未初始化，无法加载文件');
    ElMessage.warning('COS服务未初始化，无法加载文件');
    return;
  }
  
  internalLoading.value = true;
  
  try {
    if (process.env.NODE_ENV === 'development') {
      console.log('开始从COS加载文件，当前路径:', currentPath.value);
    }
    
    const result = await cosFileService.listFiles(currentPath.value);
    
    if (process.env.NODE_ENV === 'development') {
      console.log('COS返回结果:', result);
    }
    
    // 检查是否为空目录
    if (result.directories.length === 0 && result.files.length === 0) {
      if (process.env.NODE_ENV === 'development') {
        console.warn('COS返回空内容，可能路径配置有误或权限不足');
      }
      ElMessage.warning(`目录 ${currentPath.value || '根目录'} 为空或无访问权限`);
    }
    
    // 合并目录和文件，优化数组操作
    internalFiles.value = result.directories.concat(result.files);
  } catch (error) {
    console.error('加载文件失败:', error);
    ElMessage.error('加载文件失败: ' + (error.message || '未知错误'));
    internalFiles.value = [];
  } finally {
    internalLoading.value = false;
  }
};

// 刷新文件列表
const refreshFiles = async () => {
  if (props.useCosService) {
    await filePreviewStore.loadFiles(true);
  } else {
    emit('refresh');
  }
};

// 预览文件
const previewFile = (file) => {
  selectedFile.value = file;
  previewDialogVisible.value = true;
};

// 在阅读器中打开文件
const openFileInReader = (file) => {
  // 使用Pinia store保存文件信息
  filePreviewStore.setFile(file);
  
  // 发送事件
  emit('file-read', file);
  
  // 关闭文件浏览器对话框
  if (previewDialogVisible.value) {
    previewDialogVisible.value = false;
  }
  
  // 导航到文件阅读器页面
  router.push('/file-reader');
};

// 下载文件
const downloadFile = (file) => {
  // 检查下载权限
  if (!permissionStore.canDownload) {
    ElMessage.warning(permissionStore.downloadDisabledMessage);
    return;
  }
  
  if (props.useCosService) {
    cosFileService.downloadFile(file.key, file.name);
  } else {
    emit('file-download', file);
    
    try {
      const link = document.createElement('a');
      link.href = file.url;
      link.download = file.name;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      ElMessage.success('文件下载已开始');
    } catch (err) {
      console.error('下载文件失败:', err);
      ElMessage.error('下载文件失败，请重试');
    }
  }
};

// 显示文件信息
const showFileInfo = (file) => {
  selectedFile.value = file;
  fileInfoDialogVisible.value = true;
};

// 显示创建文件夹对话框
const showCreateFolderDialog = () => {
  folderForm.value.name = '';
  createFolderDialogVisible.value = true;
};

// 创建文件夹
const createFolder = async () => {
  if (!folderForm.value.name) {
    ElMessage.warning('请输入文件夹名称');
    return;
  }
  
  creatingFolder.value = true;
  
  try {
    if (props.useCosService) {
      await cosFileService.createFolder(folderForm.value.name, currentPath.value);
      ElMessage.success(`文件夹 ${folderForm.value.name} 创建成功`);
      await refreshFiles();
    } else {
      emit('folder-create', {
        name: folderForm.value.name,
        path: currentPath.value
      });
    }
    
    createFolderDialogVisible.value = false;
  } catch (error) {
    console.error('创建文件夹失败:', error);
    ElMessage.error('创建文件夹失败，请重试');
  } finally {
    creatingFolder.value = false;
  }
};

// 显示上传文件对话框
const showUploadDialog = () => {
  uploadFiles.value = [];
  uploadDialogVisible.value = true;
};

// 处理文件选择
const handleFileChange = (file, fileList) => {
  uploadFiles.value = fileList;
};

// 上传选中的文件
const uploadSelectedFiles = async () => {
  if (!uploadFiles.value.length) {
    ElMessage.warning('请选择要上传的文件');
    return;
  }
  
  uploading.value = true;
  
  try {
    if (props.useCosService) {
      for (const file of uploadFiles.value) {
        await cosFileService.uploadFile(file.raw, currentPath.value);
      }
      ElMessage.success(`上传完成`);
      await refreshFiles();
    } else {
      emit('file-upload', {
        files: uploadFiles.value.map(f => f.raw),
        path: currentPath.value
      });
    }
    
    uploadDialogVisible.value = false;
  } catch (error) {
    console.error('上传文件失败:', error);
    ElMessage.error('上传文件失败，请重试');
  } finally {
    uploading.value = false;
  }
};

// 确认删除文件
const confirmDeleteFile = (file) => {
  ElMessageBox.confirm(
    `确定要删除${file.type === 'directory' ? '文件夹' : '文件'} ${file.name} 吗？`,
    '删除确认',
    {
      confirmButtonText: '删除',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    try {
      if (props.useCosService) {
        await cosFileService.deleteFile(file.key);
        ElMessage.success(`删除成功`);
        await refreshFiles();
      } else {
        emit('file-delete', file);
      }
    } catch (error) {
      console.error('删除文件失败:', error);
      ElMessage.error('删除文件失败，请重试');
    }
  }).catch(() => {
    // 取消删除
  });
};

// 初始化COS服务
const initCosService = async () => {
  if (!props.useCosService) return false;
  
  try {
    console.log('正在初始化COS服务，配置:', props.cosConfig);
    const initialized = cosFileService.init(props.cosConfig);
    if (initialized) {
      console.log('COS服务初始化成功，路径前缀:', props.cosConfig.Prefix);
      return true;
    } else {
      console.error('初始化COS服务失败，无法获取文件列表');
      ElMessage.error('初始化COS服务失败');
      return false;
    }
  } catch (error) {
    console.error('初始化COS服务失败:', error);
    ElMessage.error('初始化COS服务失败: ' + (error.message || '未知错误'));
    return false;
  }
};

// 监听加载状态
watch(() => props.loading, (newVal) => {
  if (!props.useCosService) {
    internalLoading.value = newVal;
  }
});

// 监听路径变化，清空选中状态
watch(() => filePreviewStore.currentPath, () => {
  // 路径变化时清空选中状态
  selectedFile.value = null;
});

// 组件挂载 - 优化性能
onMounted(async () => {
  if (process.env.NODE_ENV === 'development') {
    console.log('FileExplorer组件挂载, 使用COS:', props.useCosService);
  }
  
  // 初始化时清空选中状态
  selectedFile.value = null;
  
  if (props.useCosService) {
    const initialized = await initCosService();
    
    if (process.env.NODE_ENV === 'development') {
      console.log('COS服务初始化结果:', initialized);
    }
    
    if (initialized) {
      // 如果store中已有路径，使用store中的路径
      if (filePreviewStore.currentPath !== '') {
        if (process.env.NODE_ENV === 'development') {
          console.log('使用store中的路径:', filePreviewStore.currentPath);
        }
      } else {
        // 否则设置为空路径
        if (process.env.NODE_ENV === 'development') {
          console.log('设置默认空路径');
        }
        await filePreviewStore.setPath('', true);
      }
    }
  } else {
    internalFiles.value = props.files;
  }
});
</script>

<style scoped>
.file-explorer {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: white;
  border-radius: 8px;
  overflow: hidden;
}

.explorer-header {
  padding: 16px;
  background-color: #f8fafc;
  border-bottom: 1px solid #e5e7eb;
}

.explorer-body {
  flex: 1;
  overflow: auto;
  padding: 16px;
  position: relative;
}

/* 加载状态 */
.loading-container {
  padding: 24px;
}

/* 骨架屏样式 */
.skeleton-wrapper {
  padding: 16px;
}

.skeleton-header {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.skeleton-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.skeleton-item {
  display: flex;
  align-items: center;
  padding: 8px;
  border-radius: 4px;
  background-color: #f9fafb;
}

/* 空状态样式 */
.empty-container {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.empty-state {
  margin: 0;
}
</style> 